Release 10.1A: OpenEdge Development:
Progress 4GL Handbook


Useful procedure attributes and methods

There are many procedure attributes you can access through the procedure’s handle. This section introduces you to a few of them.

FILE-NAME attribute

After you run a persistent procedure, you can query its FILE-NAME attribute to see the name of the procedure file, including any pathname it was run with. This attribute can be useful to identify a procedure so that you can run something in its handle or access other attributes.

PRIVATE-DATA attribute

There is a character attribute available on every handle, including procedure handles, called PRIVATE-DATA. It is there specifically so that you can store any value you want on the handle, to help identify the object it points to, or to store other information about the object. The PRIVATE-DATA attribute is not used by Progress in any way; it is strictly there for your application use. You could, for example, store a category of object in the PRIVATE-DATA handle when you run the procedure, or the value of one or more parameters that were passed in to the procedure to give it a distinctive function. Because you might run the same procedure file in numerous ways, for example with different input parameters or different settings that you establish in other ways, the PRIVATE-DATA attribute gives you the ability to identify it in any way you need to.

INTERNAL-ENTRIES attribute

The INTERNAL-ENTRIES attribute returns a comma-separated list of all the internal procedures in the procedure file, and also any user-defined functions, which you’ll learn about a little later. This can help you identify the location of a routine you need to run.

GET-SIGNATURE method

Given the name of any internal procedure or function in a procedure file, you can get its signature, that is, the list of parameters it requires, using the GET-SIGNATURE method on the procedure handle. This is considered a method rather than an attribute simply because it requires an input parameter, the name of the routine you want the signature for. You can also pass in a blank argument to get the signature of the external procedure itself.

GET-SIGNATURE returns a string in this format:

type, fn-return-type, mode name data-type [ , mode name data-type ], . . . 

The type is the type of entry point and its possible values are:

The fn-return-type is the data type that a function returns. For an internal procedure, this element of the signature is blank.

Following the second comma is a list of the parameter descriptions. Each description is a space-delimited list of three elements:

As an example, here is a very simple procedure file that contains an internal procedure and a user-defined function:

/* h-testsig.p -- tests GET-SIGNATURE */ 
DEFINE INPUT PARAMETER cVar AS CHAR. 
PROCEDURE TestProc: 
    DEFINE OUTPUT PARAMETER iValue AS INT. 
    /* some procedure code */ 
END. 
FUNCTION TestFunc RETURNS INTEGER (INPUT dValue AS DECIMAL): 
    /* some function code */ 
END. 

The h-testsig.p procedure takes an INPUT parameter, the TestProc internal procedure uses an OUTPUT parameter, and the TestFunc function takes an INPUT parameter and returns the data type INTEGER.

Here’s another procedure that uses GET-SIGNATURE to get the signatures of all these routines:

/* Procedure h-mainsig.p -- uses GET-SIGNATURE to return the signatures 
   of a procedure and its internal-entries */ 
DEFINE VARIABLE hProc    AS HANDLE     NO-UNDO. 
DEFINE VARIABLE iProc    AS INTEGER    NO-UNDO. 
DEFINE VARIABLE cEntries AS CHARACTER  NO-UNDO. 
DEFINE VARIABLE cMessage AS CHARACTER  NO-UNDO. 
RUN h-testsig.p PERSISTENT SET hProc (INPUT "aa"). 
cEntries = hproc:INTERNAL-ENTRIES. 
cMessage = THIS-PROCEDURE:FILE-NAME + ": " + hproc:GET-SIGNATURE(""). 
DO iProc = 1 TO NUM-ENTRIES(cEntries): 
    cMessage = cMessage + CHR(10) + 
               ENTRY(iProc, cEntries) + ": " +  
               hproc:GET-SIGNATURE(ENTRY(iProc, cEntries)).     
END. 
MESSAGE cMessage VIEW-AS ALERT-BOX. 

This procedure executes as follows:

  1. h-mainsig.p runs h-testsig.p persistent and saves off its procedure handle.
  2. h-mainsig.p gets the INTERNAL-ENTRIES attribute of the procedure, which should have the value TestProp,TestFunc.
  3. It begins to build up a character string to display later with a MESSAGE statement. The first entry in the message string is THIS-PROCEDURE:FILE-NAME. Because the built-in handle function THIS-PROCEDURE evaluates to the handle of the currently running procedure, this should return its filename, h-mainsig.p. Passing the empty string to GET-SIGNATURE returns the signature of the external procedure itself.
  4. The code loops through all the entries in the INTERNAL-ENTRIES attribute, and for each once, saves off its name and signature.
  5. To simulate a series of SKIP keywords that you could put into a MESSAGE statement, the code adds a new line character after the signature of each entry. The CHR(n) Progress built-in function takes an INTEGER value that represents the ASCII character code of any character, whether printable or not, and returns that ASCII character. In this case, 10 represents the new line character.

Figure 13–8 shows the message you see when you load h-mainsig.p into an editor window and run it.

Figure 13–8: Message box for h-mainsig.p

Interesting. The value of THIS-PROCEDURE:FILE-NAME isn’t what you expect. Instead you see what looks like a temporary filename. And that’s exactly what it is. When you run a procedure from the Procedure Editor or from the AppBuilder just by loading it or typing code into the editor and then clicking the Run button or pressing F2, the tool doesn’t actually run the saved procedure. In fact, you might not yet have saved the procedure file at all, or you might have changed it since you saved it. What you run is the code that is currently in the editor window or the AppBuilder’s Section Editor, depending on which tool you’re using. The tool gives this code a temporary filename, saves it off into that file, and runs it from there. That’s why you see this filename in the message box.

To see the filename you expected, rather than loading h-mainsig.p into an editor window and running it from there:

  1. Type this statement into a New Procedure window:
  2. Run this to see the result you expect:

Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095